﻿/// <reference path="http://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js" />
/// This class inherits from ASP.NET Ajax Sys.UI.Control (see last line in file for code that inherits)
/// and is our custom control that represents all the functionality of our map

//register namespace with ASP.NET Ajax
Type.registerNamespace("WebSericeBingMaps");

//the constructor for our control, as we are inheriting from Sys.UI.Control it takes a UI element as the single
//parameter
WebSericeBingMaps.SimplePointsMap = function (element) {
    //define member variables
    this._bingmap = null;
    this._bingmapskey;
    this._lat = null;
    this._lon = null;
    this._zoom = null;
    this._ds = null;
    this._infobox = null;
    this._loadingmsg = "loading please wait...";
    //call base class initialize
    WebSericeBingMaps.SimplePointsMap.initializeBase(this, [element]);
}
//the class 'prototype' that describes the properties and methods of the class
//private methods are marked with _MethodName purely to help you distiguish them
WebSericeBingMaps.SimplePointsMap.prototype = {
    //ASP.NET ajax method in Sys.UI.Control for initializing this control
    initialize: function () {
        //setup map control
        this._createMapControl();
        //create webservice proxy as defined by autogenerated js from web service
        this._ds = new WebServiceBingMaps.IDataService();
    },

    //methods
    //#region

    //method that creates the Bing Maps control and wires up any events we need
    _createMapControl: function () {
        var mapOptions = {
            credentials: this._bingmapskey,
            mapTypeId: Microsoft.Maps.MapTypeId.aerial,
            center: { latitude: this._lat, longitude: this._lon },
            zoom: this._zoom
        }

        this._bingmap = new Microsoft.Maps.Map(this.get_element(), mapOptions);

        //wire up map events
        Microsoft.Maps.Events.addHandler(this._bingmap, 'viewchangeend', Function.createDelegate(this, this._onMapMoved));

        //create infobox ready for use, only using single infobox for all pushpins to save adding more and more divs to dom
        //using a delegate for the handler so we keep this class in scope http://msdn.microsoft.com/en-us/library/dd393582.aspx
        this._infobox = $create(Microsoft.Maps.Ext.InfoBox, { Description: this._loadingmsg }, null, null, this._bingmap);

        //attach infobox shown event handler, using a delegate for the handler so we keep this class in scope
        //http://msdn.microsoft.com/en-us/library/dd393582.aspx
        this._infobox.add_shown(Function.createDelegate(this, this._onInfoBoxShown));
    },

    //method calls web service and loads data
    _loadData: function (topleftlatlon, bottomrightlatlon) {
        //call webservice getschools method passing parameters, on fail method and on sucess method
        //uses the javascript proxy this._ds (we defined at the top of the class) that is automatically generated
        //by referenceing the webservice as a script in the html page
        this._ds.GetSchools(topleftlatlon.latitude, topleftlatlon.longitude, bottomrightlatlon.latitude, bottomrightlatlon.longitude, 0, Function.createDelegate(this, this._onMapDataLoaded), this._webServiceFailed, null);

    },
    //handles the infobox controls shown event, passing e which is the infobox object itself
    _onInfoBoxShown: function (e) {
        var el = e.get_DomElement();
        var id = e.get_parent().getId(); //get the parent of the infobox (the pushpin) and then get the id

        //reset loading message
        e.set_Description(this._loadingmsg);

        //call GetSchool webservice method passing in parameters, on fail method and on sucess method
        //uses the javascript proxy this._ds (we defined at the top of the class) that is automatically generated
        //by referenceing the webservice as a script in the html page
        this._ds.GetSchool(id, this._onPushpinDataLoaded, this._webServiceFailed, e); //passing e (the infobox object) as the usercontext as we will need this in the success method
    },

    //#endregion

    //event handlers
    //#region

    //handles the bing maps move events
    _onMapMoved: function () {
        //call web service
        var bounds = this._bingmap.getBounds();
        //built in MSAjax method for logging to javascript console
        Sys.Debug.trace("calling map data load");
        this._loadData(bounds.getNorthwest(), bounds.getSoutheast());
    },

    //used to handle errors from web service call
    _webServiceFailed: function (err) {

    },

    //handles a successful web service call for the map search
    _onMapDataLoaded: function (results) {
        //built in MSAjax method for logging to javascript console
        Sys.Debug.trace("complete loaded " + results.length);

        //clear map's existing pushpins before plotting new ones
        this._bingmap.entities.clear();

        //loop results which is an array of JSON objects representing SchoolDTO in javascript
        for (var i = 0; i < results.length; i++) {
            //title is a custom property we have added
            var pushpin = new Microsoft.Maps.Pushpin({ latitude: results[i].Latitude, longitude: results[i].Longitude }, { id: results[i].Id.toString() });
            //assign infobox
            pushpin.title = results[i].Name;
            pushpin.setInfoBox(this._infobox);
            this._bingmap.entities.push(pushpin);

        }
    },

    //handles a successful web service call for details of a pushpin
    _onPushpinDataLoaded: function (result, context) {
        //update infobox with data using ms ajax stringbuilder
        var sb = new Sys.StringBuilder(result.Address1 + ",<br />");
        if(result.Address2) sb.append(result.Address2 + ",<br />");
        if (result.Address3) sb.append(result.Address3 + ",<br />");
        if (result.Postcode) sb.append(result.Postcode + ".<br />");
        sb.append("Type of school - " + result.SchoolTypeName);

        context.set_Description(sb.toString()); //TODO all details
    },
    //#endregion

    //properties
    //#region

    //used to get and set the bing maps key
    get_BingmapsKey: function () {
        return this._bingmapskey;
    },
    set_BingmapsKey: function (v) {
        this._bingmapskey = v;
    },
    //used to set and get the maps location
    get_Latitude: function () {
        return this._lat;
    },
    set_Latitude: function (v) {
        this._lat = v;
    },
    get_Longitude: function () {
        return this._lon;
    },
    set_Longitude: function (v) {
        this._lon = v;
    },
    //used to set and get the maps zoom level
    get_Zoom: function () {
        return this._zoom;
    },
    set_Zoom: function (v) {
        this._zoom = v;
    },

    //#endregion

    //ASP.NET ajax method in Sys.UI.Control for disposing resources
    dispose: function () {
        if (this._bingmap) this._bingmap = null;
    }
}

WebSericeBingMaps.SimplePointsMap.registerClass('WebSericeBingMaps.SimplePointsMap', Sys.UI.Control);
